using System;
using System.Collections.Generic;
using System.Text;

namespace Dare.Utilities.Components
{
    public class PagingInfo
    {
        public event EventHandler OnPageIndexChanged;
        public event EventHandler OnPageCountChanged;
        public event EventHandler OnItemCountChanged;
        public event EventHandler OnPageSizeChanged;

        private int pageSize;

        public int PageSize
        {
            get { return pageSize; }
        }
        private int pageIndex;

        public int PageIndex
        {
            get { return pageIndex; }
            set
            {
                UpdatePageIndex(value);
            }
        }
        private int itemCount;

        public int ItemCount
        {
            get { return itemCount; }
            set
            {
                if (itemCount != value)
                {
                    itemCount = value >= 0 ? value : -1;
                    if (OnItemCountChanged != null)
                        OnItemCountChanged(this, new EventArgs());
                    UpdatePageCount();
                }
            }
        }

        private int pageCount;

        public int PageCount
        {
            get { return pageCount; }
        }

        public int PageNo
        {
            get
            {
                return pageIndex + 1;
            }
            set
            {
                PageIndex = value - 1;
            }
        }

        public bool IsReady
        {
            get
            {
                return itemCount >= 0;
            }
        }

        public void Reset()
        {
            ItemCount = -1;
        }

        public void GotoFirst()
        {
            PageIndex = 0;
        }

        public void GotoLast()
        {
            PageIndex = pageCount > 0 ? pageCount - 1 : 0;
        }

        public void GotoNext()
        {
            PageIndex++;
        }

        public void GotoPrevious()
        {
            PageIndex--;
        }

        public PagingInfo(int pageSize)
        {
            itemCount = -1;
            pageCount = 0;
            pageIndex = -1;
            this.pageSize = pageSize > 0 ? pageSize : 0;
        }

        public PagingInfo()
        {
            itemCount = -1;
            pageCount = 0;
            pageIndex = -1;
            pageSize = 0;
        }

        public bool Enabled
        {
            get { return pageSize > 0; }
        }

        public void Enable(int pageSize)
        {
            int prevPageSize = this.pageSize;
            this.pageSize = pageSize > 0 ? pageSize : 0;
            UpdatePageCount();
            if (prevPageSize != this.pageSize)
            {
                if (OnPageSizeChanged != null)
                    OnPageSizeChanged(this, new EventArgs());
            }
        }

        public void Disable()
        {
            Enable(0);
        }

        private void UpdatePageCount()
        {
            int prevPageCount = pageCount;

            if (IsReady)
            {
                if (pageSize > 0)
                {
                    pageCount = (int)Math.Ceiling((double)itemCount / pageSize);
                }
                else
                {
                    pageCount = 1;
                }
            }
            else
            {
                pageCount = 0;
            }

            if (prevPageCount != pageCount)
            {
                if (OnPageCountChanged != null)
                    OnPageCountChanged(this, new EventArgs());
            }

            UpdatePageIndex(pageIndex);
        }

        private void UpdatePageIndex(int index)
        {
            int prevPageIndex = pageIndex;
            if (index < 0 || pageCount < 1)
            {
                pageIndex = pageCount > 0 ? 0 : -1;
            }
            else if (index >= pageCount)
            {
                pageIndex = pageCount - 1;
            }
            else
            {
                pageIndex = index;
            }

            if (prevPageIndex != pageIndex)
            {
                if (OnPageIndexChanged != null)
                    OnPageIndexChanged(this, new EventArgs());
            }
        }
    }
}
